﻿using System;
using System.Collections.Generic;
using System.Text;
using Slaks.Graphs.Algorithms;
using DataInput;
using Slaks.Graphs.GraphBuilder;

namespace Slaks.Graphs
{
    public class ClusteringBase : IClustering
    {
        protected const String NumberOfClustersParam = "Number of Clusters";        

        protected GraphDistanceBase m_graphDistanceMeasure;
        protected int m_numberOfClusters;
        protected GraphList[] m_graphClusters;
        
        #region IClustering Members

        public virtual GraphList[] Apply(GraphList graphs)
        {
            throw new NotImplementedException();
        }

        public virtual string GetName()
        {
            return GetType().Name;
        }

        #endregion

        public virtual List<Field> GetDynamicFields(IRepresentation BT)
        {
            List<Field> fields = new List<Field>();
            fields.Add(new TextField(NumberOfClustersParam, "Number of Clusters:", "3", false, true ));
            string[] DA = DistanceAlgFactory.Instance.GetSuitableDistanceAlgorithms(BT);
            Dictionary<string, object> distanceAlgorithms = new Dictionary<string, object>();
            for (int i = 0; i < DA.Length; i++)
                distanceAlgorithms.Add(DA[i], DA[i]);
            if ( DA.Length > 0 )
                fields.Add(new ListField(GraphDistanceBase.DistanceAlgorithmParam, "Distance Algorithm:", DA [ 0 ], distanceAlgorithms, false));
            return fields;
        }

        public virtual void SetDynamicValues(IEnumerable<Field> fields)
        {
            foreach (var field in fields)
            {
                if (field.FieldName == NumberOfClustersParam)
                    m_numberOfClusters = int.Parse(field.Value.ToString());
                if (field.FieldName == GraphDistanceBase.DistanceAlgorithmParam)
                    m_graphDistanceMeasure = DistanceAlgFactory.Instance.GetInstance(field.Value.ToString()); 
            }
        }

        public int CountGraphs()
        {
            int count = 0;
            foreach (GraphList cluster in this.GetGraphClusters())
            {
                count += cluster.Count;
            }
            return count;
        }

        #region IClustering Members

        public virtual GraphDistanceBase DistanceMeasure
        {
            get
            {
                return m_graphDistanceMeasure;
            }
            set
            {
                m_graphDistanceMeasure = value;
            }
        }

        virtual public int NumberOfClusters
        {
            get
            {
                return m_numberOfClusters;
            }
            set
            {
                m_numberOfClusters = value;
            }
        }

        public GraphList[] GetGraphClusters()
        {
            return m_graphClusters;
        }

        #endregion
    }
}
